﻿/*
 * Copyright 2007-2008  Lukasz Laszko lukaszlaszko@gmail.com
 * 
 * Permission to use, copy, modify, and distribute this software
 * and its documentation for any purpose and without fee is hereby
 * granted, provided that the above copyright notice appear in all
 * copies and that both that the copyright notice and this
 * permission notice and warranty disclaimer appear in supporting
 * documentation, and that the name of the author not be used in
 * advertising or publicity pertaining to distribution of the
 * software without specific, written prior permission.
 * 
 * The author disclaim all warranties with regard to this
 * software, including all implied warranties of merchantability
 * and fitness.  In no event shall the author be liable for any
 * special, indirect or consequential damages or any damages
 * whatsoever resulting from loss of use, data or profits, whether
 * in an action of contract, negligence or other tortious action,
 * arising out of or in connection with the use or performance of
 * this software. 
 */

Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(initializeRequestHandler);

function initializeRequestHandler(sender, args)
{
    if (FileUpload.get_UploadFrame() != null)
    {
        if (sender._postBackSettings.panelID.split('|')[0] == FileUpload.updatePanelId)
        {               
            args.set_cancel(true);                                     
            
            FileUpload.request = args._request;
            FileUpload.uploadFile(null); 
        }
    }
}

var FileUpload = { 
    // fields //
    timer : null,
    uploadId : null, 
    onUploadStarted : null,
    onUploadProgress : null,
    onUploadCompleted : null, 
    onError : null,
    request : null,  
    updatePanelId : null,
    
    // properties //
    /**
     * Getter property method. This property gets selected file name
     * @returns null if file name has not been selected or file name
     */
    get_FileName : function()
    {
        var uploadFrame = document.frames[0];
            
        var uploadFileControl = uploadFrame.document.getElementById('fileInput');
        return uploadFileControl.value;   
    },
    
    get_UploadFrame : function(uploadFrameId)
    {
        try
        {
            var uploadFrame = document.frames[uploadFrameId];
            if ((uploadFrame == null) || (uploadFrameId == null))
                uploadFrame = document.frames[0];
                
            return uploadFrame;                
        }
        catch (ex)
        {
            return null;
        }
    },    
    
    // methods //
    /**
     * Starts upload statuc check timer
     */
    startTimer : function () 
    { 
        this.timer = setInterval('FileUpload.timerTick()', 1000);
    },
    
    /**
     * Stops upload status check timer
     */
    stopTimer : function () 
    {
        if (this.timer != null)
            clearInterval(this.timer);
    },
    
    /**
     * Reinvokes canceled request
     */
    reinvokeRequest : function ()
    {
        if (FileUpload.request != null)
        {
            Sys.WebForms.PageRequestManager._instance._request = FileUpload.request;
            FileUpload.request.invoke();
        }           
    },
    
    // event handlers //
    /**
     * Method registered as a handler for uplad file events
     * @param uploadFrameId id of iframe to be postbacked 
     */
    uploadFile : function (uploadFrameId) 
    {
        try
        {
            // get upload frame
            var uploadFrame = FileUpload.get_UploadFrame(uploadFrameId);
                
            
            var uploadIdControl = uploadFrame.document.getElementById('uploadId');
            this.uploadId = uploadIdControl.value;
            
            if (this.onUploadStarted != null)
                this.onUploadStarted();
            
            this.startTimer();
               
            uploadFrame.document.forms[0].submit();
            
            // store and return upload id             
            return this.uploadId;               
        }
        catch (ex)
        {
            if (FileUpload.onError != null)
                FileUpload.onError(ex);
            else
                throw ex;
        }
    },     
    
    /**
     * Event handler invoked when internal timer tick occures. On tick 
     * download status is checked.
     */
    timerTick : function () 
    {
        this.stopTimer();
        
        wRequest =  new Sys.Net.WebRequest();
        wRequest.set_url("uploadStatus.ashx?uploadId=" + this.uploadId + '&time=' + new Date().getTime());         
        wRequest.add_completed(this.requestCompleted); 
        
        var executor = new Sys.Net.XMLHttpExecutor();
        wRequest.set_executor(executor); 
        executor.executeRequest();        
    },
    
    /**
     * Event handler executed when web request completes execution. 
     * This method is intended to be used for internal purposes only
     * @param sender WebRequest related to this notification
     * @param eventArgs event parameters
     */
    requestCompleted : function (sender, eventArgs) 
    {
        try
        {
            var responseData = sender.get_responseData();
            var status = eval('(' + responseData + ')');
            
            if (status.position != status.length)
            {
                if (FileUpload.onUploadProgress != null)
                    FileUpload.onUploadProgress(status);
                    
                FileUpload.startTimer();
            }
            else
            {
                if (FileUpload.onUploadCompleted != null)
                    FileUpload.onUploadCompleted(status); 
                    
                FileUpload.reinvokeRequest();                                                                                  
            }
        }
        catch (ex)
        {
            if (FileUpload.onError != null)
                FileUpload.onError(ex);
            else
                throw ex;
        }
    },
    
    /**
     * Method utilized as an event handler by validators.
     * @returns true if upload file has been selected. Otherwise it will return false.     
     */ 
    validate : function(sender, args)
    {
        try
        {
            var fileName = FileUpload.get_FileName();
            if (fileName == null)
            {
                args.IsValid = false;
                return;
            }
            else if (fileName == '')
            {
                args.IsValid = false;
                return;
            }
            else
                args.IsValid = true;            
        }
        catch (ex)
        {
            args.IsValid = false;
        }
    }    
};
